/*
 * Definitions.h
 *
 *  Created on: Dec 9, 2012
 *      Author: omnia
 */

#include        "stdio.h"
#include		"stdlib.h"

/* Process Control Block Definitions */
// Process State
#define			NEW_STATE				90
#define			READY_STATE				91
#define			RUNNING_STATE			92
#define			WAITING_STATE			93
#define			SUSPENDED_STATE			94
//Max IDs, PCB Name, Priority
#define			MAX_PIDs				100
#define			MAX_NAME				16
#define			MAX_PRIO				200
//Message Status States
#define			RECEIVE_MSG 			60
#define			SEND_MSG 				61
#define			READY_MSG				62
#define			RECV_SUS_MSG			63
#define MAX_MSG 128
#define			MAX_MSG_COUNT			10
#include <string>
#include <strings.h>
using namespace std;
typedef struct {

	char processName[MAX_NAME + 1];
	INT32 processId;
	INT32 pri;
	INT32 time;
	INT32 state;
	INT32 parent;
	INT32 msg_state;
	INT32 msg_count;
	void *context;
	void *next;
	void *prev;
	void *Inbox;
	void *Outbox;
	UINT16  pageTable[VIRTUAL_MEM_PGS];
	INT32 disk;
} PCB;

typedef struct {
	INT32 id;
	INT32 device_ID;
	INT32 Status;
	void *next;
} EVENT_t;

typedef struct {
	INT32 dest_ID;
	INT32 src_ID;
	INT32 Length;
	char message[MAX_MSG + 1];
	void *next;
} MSG;

//Create Process
void OS_Create_Process(char *name, void *procPTR, INT32 priority, INT32 *pid,
		INT32 *error, INT32 SWITCH);
//Contexts
void make_context(PCB * PCB, void *procPTR);
void make_switch_Savecontext(PCB * PCB, void *procPTR);
void make_switch_Killcontext(PCB * PCB, void *procPTR);
void switch_Killcontext(PCB * PCB);
void switch_Savecontext(PCB * PCB);
void switch_Context(void);
//Add Queues
void readyQueue_to_timerQueue(INT32 remove_id);
void add_to_readyQueue(PCB **ptrFirst, PCB *entry);
void add_to_timerQueue(PCB **ptrFirst, PCB *entry);
void add_to_eventQueue(INT32 *device_id, INT32 *status);
INT32 add_to_Queue(PCB **ptrFirst, PCB * entry);
INT32 add_to_Outbox(MSG *entry) ;
void add_to_Inbox(PCB *dest, MSG *msgRecv);
//Remove Queues
INT32 rm_from_readyQueue(INT32 remove_id);
void rm_from_timerQueue(PCB **ptrFirst, INT32 remove_id);
void rm_from_eventQueue(INT32 remove_id);
PCB *rm_from_Queue(PCB **ptrFirst, INT32 remove_id);
//Move Queues
void timerQueue_to_readyQueue(INT32 remove_id);
//void readyQueue_to_timerQueue(INT32 remove_id);
//PCB Handle
PCB *ready_to_Wait(INT32 remove_id);
void change_Priority(INT32 process_ID, INT32 new_priority, INT32 *error);
INT32 updatePriority(INT32 process_ID, INT32 new_priority);
void wait_to_Ready(INT32 remove_id);
void ready_to_Running(void);
//Sort Queues
void timer_sort(void);
void ready_sort(void);
void swap(bool x, PCB *Prev, PCB *Curr);
//Queue Helpers
INT32 check_name(PCB **ptrFirst, char *name);
INT32 get_PCB_ID(PCB **ptrFirst, char *name, INT32 *process_ID, INT32 *error);
INT32 check_pid_ID(INT32 check_ID);
//Get PCB
PCB *get_firstPCB(PCB ** ptrFirst);
PCB *get_readyPCB(void);
//Process Handle
void terminate_Process(INT32 process_ID, INT32 *error);
void rm_children(PCB **ptrFirst, INT32 process_ID);
void suspend_Process(INT32 process_ID, INT32 *error);
void resume_Process(INT32 process_ID, INT32 *error);
//Timer Functions
INT32 get_currentTime(void);
void checkTimer(INT32 currentTime, INT32 *time);
void wake_timerList(INT32 currentTime, INT32 *number);
void Start_Timer(INT32 Time);
/*locks
 *
 */
void lockReady(void);
void unlockReady(void);
void EVENT_IDLE(void);
//Message Handle
void send_Message(INT32 dest_ID, char *message, INT32 msg_Len, INT32 *error);
void send_if_dest_Receive( MSG *tosend, INT32 dest_ID );
void target_to_Receive ( INT32 dest_ID );
void receive_Message ( INT32 src_ID, char *message,
	INT32 msg_rcvLen, INT32 *msg_sndLen, INT32 *sender_ID,  INT32 *error);
void get_msg_Inbox ( char *message, INT32 *msg_sndLen, INT32 *sender_ID);
MSG * get_outboxMessage ( INT32 src_ID );
/*			Global variables			*/
extern PCB *current_PCB;
extern PCB *pidList;
extern PCB *timerList;
extern EVENT_t *eventList;
extern INT32 event_count;
extern INT32 inc_pid;
extern INT32 total_pid;
extern INT32 inc_event ;

